package com.junjie.checkin.controller;

import com.junjie.checkin.request.auth.AuthRequest;
import com.junjie.checkin.request.auth.RefreshRequest;
import com.junjie.checkin.response.auth.AuthResponse;
import com.junjie.checkin.response.ResultStatus;
import com.junjie.checkin.response.Result;
import com.junjie.checkin.response.auth.TokenResponse;
import com.junjie.checkin.security.service.AuthDetails;
import com.junjie.checkin.security.service.JwtService;
import com.junjie.checkin.security.service.impl.JwtServiceImpl;
import com.junjie.checkin.service.AuthService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 洪浚杰
 * @description 认证控制器
 * @date 2025/6/9 12:59
 */

@RestController
@Tag(
        name = "认证管理",
        description = "用户的认证管理,包括注册,登录,令牌更新,登出操作"
)

public class AuthController {
    @Autowired
    private AuthService authService;
    @Autowired
    private JwtServiceImpl jwtService;
    @Autowired
    RedisTemplate<String,Object> redisTemplate;

    /**
     * 用户登录
     * @param request 登录数据
     * @return 响应结果,需返回用户基本数据,token和refreshToken
     */
    @Operation(
            summary = "普通用户登录",
            description = "普通用户登录前台系统",
            tags = {"认证管理"},
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    required = true,
                    description = "登录信息",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = AuthRequest.class)
                    )
            )
    )

    @PostMapping("/login")
    public Result<AuthResponse> login(@Validated @RequestBody AuthRequest request){
        AuthResponse login = authService.login(false, request.getUsername(), request.getPassword());
        return Result.getResult(ResultStatus.OK,login);
    }

    /**
     * 管理员登录
     * @param request 登录数据
     * @return 响应结果,需返回用户基本数据,token和resheshToekn
     */
    @Operation(
            summary = "管理员用户登录",
            description = "管理员登录,需要有管理员身份"
    )
    @PostMapping("/admin/login")
    public Result<AuthResponse> adminLogin(@Validated @RequestBody AuthRequest request){
        AuthResponse login = authService.login(true, request.getUsername(), request.getPassword());
        return Result.getResult(ResultStatus.OK,login);
    }

    /**
     * 用户注册,管理员不可被注册,需要到管理员页面进行添加
     * @param request 注册数据
     * @return 响应注册结果
     */
    @Operation(
            summary = "普通用户注册",
            description = "用户注册,管理员不可被注册,需要到管理员页面进行添加",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    required = true,
                    description = "登录信息",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = AuthRequest.class)
                    )
            )
    )
    @PostMapping("/register")
    public Result register(@Validated @RequestBody AuthRequest request){
            authService.register(request.getUsername(), request.getPassword());
            return Result.getResult(ResultStatus.OK);

    }



    /**
     * 更新令牌
     * @param refresh 刷新令牌
     * @return 令牌信息
     */
    @Operation(
            summary = "认证令牌更新",
            description = "登录令牌更新,会同步更新两个令牌,前端需要同时更新两个令牌",
            requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
                    required = true,
                    description = "登录信息",
                    content = @Content(
                            mediaType = "application/json",
                            schema = @Schema(implementation = RefreshRequest.class)
                    )
            )
    )
    @PostMapping("/refresh")
    public Result<TokenResponse> refreshToken(@Validated @RequestBody RefreshRequest refresh){

        // 更新新token
        TokenResponse newToken = authService.refresh(refresh.getRefresh(), refresh.getUserId());
        return Result.getResult(ResultStatus.OK,newToken);
    }

    /**
     * 用户登出
     * @param request http请求,需要拿到token数据,从而拿到用户ID
     * @return 执行结果
     */
    @Operation(
            summary = "用户登出系统",
            description = "用户登出系统,登录时包含token,token和RefreshToken失效,完成登出后,在前端保存的令牌应删除"
    )
    @PostMapping("/logout")
    public Result logout(HttpServletRequest request){
        String token = request.getHeader("Authorization");
        AuthDetails authDetails = jwtService.analyzeToken(token);
        authService.logout(authDetails.getUser().getId());
        return Result.getResult(ResultStatus.OK);
    }
}
